package org.toycode.logindemo.application.tapestry.util;

import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.tapestry5.json.JSONArray;
import org.apache.tapestry5.json.JSONObject;
import org.toycode.logindemo.application.config.Config;
import org.toycode.logindemo.application.config.Entity;
import org.toycode.logindemo.application.config.Prop;

/**
 * This utility class transforms the data model(usually some EJB 3.0 entities )
 * to another model(such as JSON object, etc).
 *
 * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
 * @version 1.0.0.1, Sep 1, 2009
 */
final public class DataModelTransformer {

    static {
        try {
            Config.load();
        } catch (final Exception ex) {
            Logger.getLogger(DataModelTransformer.class.getName()).
                    log(Level.SEVERE, null, ex);
        }
    }

    private DataModelTransformer() {
    }

    public static JSONArray transform2JSONArray(final Collection<?> objects) {
        final JSONArray ret = new JSONArray();

        for (final Object object : objects) {
            final JSONObject jsonObject = transform2JSONObject(object);
            ret.put(jsonObject);
        }

        return ret;
    }

    public static JSONObject transform2JSONObject(final Object object) {
        final JSONObject ret = new JSONObject();

        final Class<?> clazz = object.getClass();
        final String className = clazz.getName();

        try {
            for (final Entity e : Config.dataTableConfig.entities) {
                if (e.clazz.equals(className)) {
                    for (final Prop p : e.props) {
                        final String type = p.type;
                        if (type.equals("String") || type.equals("Long") ||
                            type.equals("int")) {    // TODO: should include all primitive types
                            final Object value =
                                    clazz.getMethod(p.getter, null).
                                    invoke(object, null);
                            ret.put(p.displayName, value.toString());
                        }
                    }
                }

            }
        } catch (IllegalAccessException ex) {
            Logger.getLogger(DataModelTransformer.class.getName()).
                    log(Level.SEVERE, null, ex);
        } catch (IllegalArgumentException ex) {
            Logger.getLogger(DataModelTransformer.class.getName()).
                    log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(DataModelTransformer.class.getName()).
                    log(Level.SEVERE, null, ex);
        } catch (NoSuchMethodException ex) {
            Logger.getLogger(DataModelTransformer.class.getName()).
                    log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(DataModelTransformer.class.getName()).
                    log(Level.SEVERE, null, ex);
        }

        return ret;
    }
}
